package modelovectorial.persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import modelovectorial.Palabra;
import modelovectorial.PalabraSucia;
import soporte.MySQLConnexion;

/**
 * @project DLC Final / UTN FRC 2013
 * @date Febrero de 2013
 *
 * @author Gonzalo Arribere
 * @author Gustavo Morales
 * @author Pablo Moreno
 *
 * Esta clase representa un gestor que administra todas las consultas que se
 * realizan a la base de datos, implementando el patron de diseño Singleton.
 */
public class GestorConsultas {
    //Representa la instancia de la clase a devolver para implementar el Singleton.

    private static GestorConsultas mINSTANCE = new GestorConsultas();
    //PreparedStatements para realizar las consultas precompiladas.
    private PreparedStatement consMaxIdDoc, consMaxIdTermino, consExistePalabra, consExistePalabraSucia, consDameIdTermino, consDameIdTerminoSucio;

    public static GestorConsultas getInstance() {
        return mINSTANCE;
    }

    /**
     * Constructor por defecto de la clase.
     */
    private GestorConsultas() {
        this(MySQLConnexion.getConnexion());
    }

    /**
     * Constructor por parametros que inicializa los atributos de la clase.
     *
     * @param conn una conexion a la bd.
     */
    private GestorConsultas(Connection conn) {
        try {
            consMaxIdDoc = conn.prepareStatement("select max(idDocumento) as max from documento");
            consMaxIdTermino = conn.prepareStatement("select max(idTermino) as max from termino");
            consExistePalabra = conn.prepareStatement("select idTermino from termino WHERE terminoLimpio = ?");
            consExistePalabraSucia = conn.prepareStatement("select idTerminoSucio from terminosucio WHERE termino = ?");
            consDameIdTermino = conn.prepareStatement("select idTermino from termino where terminoLimpio = ?");
            consDameIdTerminoSucio = conn.prepareStatement("select idTerminoSucio from terminosucio where termino = ?");
        } catch (SQLException ex) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Devuelve el identificador del ultimo Documento insertado en la base.
     *
     * @return entero que representa el identificador del ultimo documento
     * insertado.
     */
    public int getMaxIdDocumento() {

        int result = 0;

        ResultSet resultado_consulta = null;
        try {
            resultado_consulta = consMaxIdDoc.executeQuery();
            if (resultado_consulta.next()) {
                try {
                    // tomo el id del documento que grabe
                    result = resultado_consulta.getInt("max");
                } catch (SQLException e) {
                    Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
                }
            }
            resultado_consulta.close();
        } catch (SQLException e) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
        }
        return result;
    }

    /**
     * Devuelve el id del ultimo termino insertado en la bd.
     *
     * @return un entero que representa el identificador del ultimo termino
     * insertado en la base.
     */
    public int getMaximoIdTermino() {

        int id = 0;
        ResultSet resultado_consulta = null;
        try {
            try {
                resultado_consulta = consMaxIdTermino.executeQuery();
            } catch (SQLException ex) {
                Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, ex);
            }
            while (resultado_consulta.next()) {
                try {
                    // tomo el id del documento que grabe
                    id = resultado_consulta.getInt("max");
                } catch (SQLException e) {
                    Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
                }
            }
        } catch (SQLException e) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
        }
        return id;
    }

    /**
     * Determina la existencia o no de una palabra limpia dentro de la bd.
     *
     * @param p Palabra a buscar en la bd.
     * @return un valor booleano que si es true es porque la palabra existe
     * efectivamente y false en caso contrario.
     */
    boolean existePalabra(Palabra p) {
        boolean r = false;

        ResultSet resultadoConsulta;
        try {
            consExistePalabra.setString(1, p.getPalabraLimpia());
            resultadoConsulta = consExistePalabra.executeQuery();

            if (resultadoConsulta.next()) {
                p.setIdPalabra(resultadoConsulta.getInt("idTermino"));
                r = true;
            }
        } catch (SQLException e) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
        }

        return r;
    }

    /**
     * Determina la existencia o no de una palabra limpia con signos de
     * puntuacion dentro de la bd.
     *
     * @param ps Palabra a buscar en la bd.
     * @return un valor booleano que si es true es porque la palabra existe
     * efectivamente y false en caso contrario.
     */
    boolean existePalabraSucia(PalabraSucia ps) {
        boolean r = false;

        ResultSet resultadoConsulta;
        try {
            consExistePalabraSucia.setString(1, ps.getPalabraSucia());
            resultadoConsulta = consExistePalabraSucia.executeQuery();

            if (resultadoConsulta.next()) {
                ps.setIdTerminoSucio(resultadoConsulta.getInt("idTerminoSucio"));
                r = true;
            }
        } catch (SQLException e) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
        }
        return r;
    }

    /**
     * Devuelve el id de una palabra pasada por parametro.
     *
     * @param p palabra a determinar id.
     * @return entero que representa el identificador de la palabra.
     */
    public int dameIdTermino(Palabra p) {
        int id = 0;
        try {
            ResultSet resultado_consulta = null;
            try {
                String palabra = p.getPalabraLimpia().replace("\'", "\\\'");
                palabra = palabra.replace("\"", "\\\"");
                consDameIdTermino.setString(1, palabra);
                resultado_consulta = consDameIdTermino.executeQuery();
            } catch (SQLException e) {
                Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
            }
            while (resultado_consulta.next()) {
                try {
                    // tomo el id del termino
                    id = resultado_consulta.getInt("idTermino");
                } catch (SQLException e) {
                    Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, ex);
        }
        return id;
    }

    /**
     * Devuelve el id de una palabra con signos pasada por parametro.
     *
     * @param p palabra a determinar id.
     * @return entero que representa el identificador de la palabra con signos.
     */
    public int dameIdTerminoSucio(PalabraSucia p) {
        int id = 0;
        try {
            ResultSet resultado_consulta = null;
            try {
                String palabraSucia = p.getPalabraSucia().replace("\'", "\\\'");
                palabraSucia = palabraSucia.replace("\"", "\\\"");
                consDameIdTerminoSucio.setString(1, palabraSucia);
                resultado_consulta = consDameIdTerminoSucio.executeQuery();
            } catch (SQLException e) {
                Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
            }
            while (resultado_consulta.next()) {
                try {
                    // tomo el id del termino
                    id = resultado_consulta.getInt("idTerminoSucio");
                } catch (SQLException e) {
                    Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
                }
            }
        } catch (SQLException e) {
            Logger.getLogger(GestorConsultas.class.getName()).log(Level.SEVERE, null, e);
        }
        return id;
    }
}